package com.exocr;

import android.content.Context;
import android.text.TextUtils;

import com.baidu.ocr.sdk.OCR;
import com.baidu.ocr.sdk.OnResultListener;
import com.baidu.ocr.sdk.exception.OCRError;
import com.baidu.ocr.sdk.exception.SDKError;
import com.baidu.ocr.sdk.model.BankCardParams;
import com.baidu.ocr.sdk.model.BankCardResult;
import com.baidu.ocr.sdk.model.GeneralParams;
import com.baidu.ocr.sdk.model.GeneralResult;
import com.baidu.ocr.sdk.model.IDCardParams;
import com.baidu.ocr.sdk.model.IDCardResult;
import com.baidu.ocr.sdk.model.OcrRequestParams;
import com.baidu.ocr.sdk.model.OcrResponseResult;
import com.baidu.ocr.sdk.utils.GeneralResultParser;
import com.baidu.ocr.sdk.utils.HttpUtil;
import com.baidu.ocr.sdk.utils.ImageUtil;
import com.baidu.ocr.sdk.utils.OcrResultParser;
import com.baidu.ocr.sdk.utils.Parser;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class OCRHelper {
    public static void doOCR(OCR ocrInstance,String orcFullUrl,  OCRTypes ocrType,String filePath,final OCRCallBack callBack){
        if (ocrInstance==null||ocrType==null||TextUtils.isEmpty(filePath)){
            if (callBack!=null){
                callBack.result(null);
            }
            return;
        }
        OnResultListener ocrResponseResultListener= new OnResultListener<OcrResponseResult>() {
            @Override
            public void onResult(OcrResponseResult ocrResponseResult) {
                if (callBack!=null){
                    callBack.result(ocrResponseResult);
                }
            }

            @Override
            public void onError(OCRError ocrError) {
                if (callBack!=null) {
                    callBack.result(ocrError);
                }
            }
        };
        OnResultListener ocrGeneralResultListener= new OnResultListener<GeneralResult>() {
            @Override
            public void onResult(GeneralResult ocrResponseResult) {
                if (callBack!=null){
                    callBack.result(ocrResponseResult);
                }
            }

            @Override
            public void onError(OCRError ocrError) {
                if (callBack!=null) {
                    callBack.result(ocrError);
                }
            }
        };
        try {
            String ocrFunc=ocrType.getOcrFunc();
            String ocrUrl=ocrType.getUrlRoot()+ocrFunc;
            if (!TextUtils.isEmpty(orcFullUrl)){
                ocrUrl=orcFullUrl;
            }
            boolean frontOrBackType=ocrType.getFrontOrBackType()==0;
            if (OCRTypes.ocr_type_common.equals(ocrType.getOcrType())){
                //通用文字
                GeneralParams param = new GeneralParams();
                param.setImageFile(new File(filePath));
                if (OCRTypes.OCRCommonBranch.type_general_basic.equals(ocrFunc)){
                    ocrInstance.recognizeGeneralBasic(param,ocrGeneralResultListener);
                }else if (OCRTypes.OCRCommonBranch.type_general.equals(ocrFunc)){
                    ocrInstance.recognizeGeneral(param,ocrGeneralResultListener);
                }else if (OCRTypes.OCRCommonBranch.type_accurate_basic.equals(ocrFunc)){
                    ocrInstance.recognizeAccurateBasic(param,ocrGeneralResultListener);
                }else if (OCRTypes.OCRCommonBranch.type_accurate.equals(ocrFunc)){
                    ocrInstance.recognizeAccurate(param,ocrGeneralResultListener);
                }
            }else if (OCRTypes.ocr_type_card.equals(ocrType.getOcrType())){
                //卡证文字
                if (OCRTypes.OCRCardBranch.type_idcard.equals(ocrFunc)){
                    IDCardParams param = new IDCardParams();
                    param.setImageFile(new File(filePath));
                    // 设置身份证正反面
                    param.setIdCardSide(frontOrBackType?IDCardParams.ID_CARD_SIDE_FRONT:IDCardParams.ID_CARD_SIDE_BACK);
                    // 设置方向检测
                    param.setDetectDirection(true);
                    // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
                    // param.setImageQuality(20);
                    OnResultListener listener= new OnResultListener<IDCardResult>() {
                        @Override
                        public void onResult(IDCardResult ocrResponseResult) {
                            if (callBack!=null){
                                callBack.result(ocrResponseResult);
                            }
                        }

                        @Override
                        public void onError(OCRError ocrError) {
                            if (callBack!=null) {
                                callBack.result(ocrError);
                            }
                        }
                    };
                    ocrInstance.recognizeIDCard(param,listener);
                }else if (OCRTypes.OCRCardBranch.type_bankcard.equals(ocrFunc)){
                    BankCardParams param = new BankCardParams();
                    param.setImageFile(new File(filePath));
                    OnResultListener listener= new OnResultListener<BankCardResult>() {
                        @Override
                        public void onResult(BankCardResult ocrResponseResult) {
                            if (callBack!=null){
                                callBack.result(ocrResponseResult);
                            }
                        }

                        @Override
                        public void onError(OCRError ocrError) {
                            if (callBack!=null) {
                                callBack.result(ocrError);
                            }
                        }
                    };
                    ocrInstance.recognizeBankCard(param,listener);
                }else if (OCRTypes.OCRCardBranch.type_business_license.equals(ocrFunc)||
                        OCRTypes.OCRCardBranch.type_business_card.equals(ocrFunc)||
                        OCRTypes.OCRCardBranch.type_passport.equals(ocrFunc)){
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    ocrInstance.recognizePassport(param, ocrResponseResultListener);
                }else{
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    if (OCRTypes.OCRCardBranch.type_HK_Macau_exitentrypermit.equals(ocrFunc)){
                        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                    }else if (OCRTypes.OCRCardBranch.type_taiwan_exitentrypermit.equals(ocrFunc)){
                        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                    }else if (OCRTypes.OCRCardBranch.type_household_register.equals(ocrFunc)){
                        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                    }else if (OCRTypes.OCRCardBranch.type_birth_certificate.equals(ocrFunc)){
                        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                    }else if (OCRTypes.OCRCardBranch.type_multi_card_classify.equals(ocrFunc)){
                        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                    }
                }
            }else if (OCRTypes.ocr_type_bill.equals(ocrType.getOcrType())){
                //票据文字
                OcrRequestParams param = new OcrRequestParams();
                param.setImageFile(new File(filePath));
                if (OCRTypes.OCRBillBranch.type_vat_invoice.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_quota_invoice.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_invoice.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_train_ticket.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_taxi_receipt.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_air_ticket.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_bus_ticket.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_toll_invoice.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_receipt.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_insurance_documents.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRBillBranch.type_lottery.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }
            }else if (OCRTypes.ocr_type_car.equals(ocrType.getOcrType())){
                //汽车场景
                OcrRequestParams param = new OcrRequestParams();
                param.setImageFile(new File(filePath));
                if (OCRTypes.OCRCarBranch.type_vehicle_license.equals(ocrFunc)){
                    ocrInstance.recognizeVehicleLicense(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRCarBranch.type_driving_license.equals(ocrFunc)){
                    ocrInstance.recognizeDrivingLicense(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRCarBranch.type_license_plate.equals(ocrFunc)){
                    ocrInstance.recognizeLicensePlate(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRCarBranch.type_vin_code.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRCarBranch.type_vehicle_invoice.equals(ocrFunc)){
                    ocrInstance.recognizeVatInvoice(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRCarBranch.type_vehicle_certificate.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }
            }else if (OCRTypes.ocr_type_educate.equals(ocrType.getOcrType())){
                //教育场景文字
                OcrRequestParams param = new OcrRequestParams();
                param.setImageFile(new File(filePath));
                if (OCRTypes.OCREducateBranch.type_handwriting.equals(ocrFunc)){
                    ocrInstance.recognizeHandwriting(param, ocrResponseResultListener);
                }else if (OCRTypes.OCREducateBranch.type_formula.equals(ocrFunc)){
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }
            }else if (OCRTypes.ocr_type_extra.equals(ocrType.getOcrType())){
                //其他文字识别
                if (OCRTypes.OCRExtraBranch.type_webimage.equals(ocrFunc)){
                    GeneralParams param = new GeneralParams();
                    param.setImageFile(new File(filePath));
                    ocrInstance.recognizeWebimage(param, ocrGeneralResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_webimage_loc.equals(ocrFunc)) {
                    GeneralParams param = new GeneralParams();
                    param.setImageFile(new File(filePath));
                    callOCR2(ocrInstance,ocrUrl, param, ocrGeneralResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_doc_analysis.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_meter.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_request.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_form.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_numbers.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    ocrInstance.recognizeNumbers(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_qrcode.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    ocrInstance.recognizeQrcode(param, ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_seal.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }else if (OCRTypes.OCRExtraBranch.type_facade.equals(ocrFunc)) {
                    OcrRequestParams param = new OcrRequestParams();
                    param.setImageFile(new File(filePath));
                    callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
                }
            }
        }catch (Exception e){
            if (callBack!=null){
                String msg=e!=null? e.toString():null;//https://tyocr.xfyun.cn/v2/ocr
                SDKError error = new SDKError(283504, !TextUtils.isEmpty(msg)?msg:"Network error", e);
                callBack.result(error);
            }
            e.printStackTrace();
        }
    }
    //表格文字识别(异步接口) 专用方法
    //获取结果的方法
    //request_id:发送表格文字识别请求时返回的request id
    //result_type:期望获取结果的类型，取值为“excel”时返回xls文件的地址，取值为“json”时返回json格式的字符串,默认为”excel”
    public static void get_request_result(OCR ocrInstance,String orcFullUrl, String request_id,String result_type,final OCRCallBack callBack) {
        if (TextUtils.isEmpty(request_id)){
            if (callBack!=null){
                callBack.result(null);
            }
            return;
        }
        if (ocrInstance==null){
            if (callBack!=null){
                callBack.result(null);
            }
            return;
        }
        OnResultListener ocrResponseResultListener= new OnResultListener<OcrResponseResult>() {
            @Override
            public void onResult(OcrResponseResult ocrResponseResult) {
                if (callBack!=null){
                    callBack.result(ocrResponseResult);
                }
            }

            @Override
            public void onError(OCRError ocrError) {
                if (callBack!=null) {
                    callBack.result(ocrError);
                }
            }
        };
        OcrRequestParams param = new OcrRequestParams();
        param.putParam(request_id,request_id);
        if (result_type!=null){
            param.putParam(result_type,result_type);
        }
        String ocrUrl=OCRTypes.urlRoot_bd_v1+ "form_ocr/get_request_result";
        if (!TextUtils.isEmpty(orcFullUrl)){
            ocrUrl=orcFullUrl;
        }
        callOCR(ocrInstance,ocrUrl,param,ocrResponseResultListener);
    }
        //////////////////////////////////////////////////////////////////////////
    ////不需要关注以下程序
    //////////////////////////////////////////////////////////////////////////
    public static Object reflectionFunc(Object obj,String func,Object[] params,Class[] cls){
        Object res=null;
        try {
            Class clazz = obj.getClass();
            Method m = null;
            if (params!=null){
                m = clazz.getDeclaredMethod(func, cls);
            }else {
                m=clazz.getDeclaredMethod(func);
            }
            if (m!=null){
                m.setAccessible(true); // 抑制Java的访问控制检查
                res= m.invoke(obj, params);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return res;
    }
    public static void callOCR(OCR ocrInstance,final String url,final OcrRequestParams params, final OnResultListener<OcrResponseResult> listener) {
        String targetUrl = url + (url.endsWith("?") ? "" : "?");
        reflectionFunc(ocrInstance, "recognizeCommon", new Object[]{params, listener, targetUrl}, new Class[]{OcrRequestParams.class, OnResultListener.class, String.class});
    }
    private static void callOCR2(OCR ocrInstance,final String url,final GeneralParams param, final OnResultListener<GeneralResult> listener) {
        String targetUrl = url + (url.endsWith("?") ? "" : "?");
        reflectionFunc(ocrInstance, "recognizeLocation", new Object[]{param, listener, targetUrl}, new Class[]{GeneralParams.class, OnResultListener.class, String.class});
    }
    ////**********************
    ////以下callOCR & callOCR2 方法能实现以上同样的功能
    ////**********************
//    public static Object reflectionParam(Object obj,String fieldName){
//        Object res=null;
//        try {
//            Class clazz = obj.getClass();
//            Field m = clazz.getField(fieldName);
//            if (m!=null){
//                m.setAccessible(true); // 抑制Java的访问控制检查
//                res=m.get(obj);
//            }
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return res;
//    }
//     public static void callOCR(final OCR ocrInstance, final String url,final OcrRequestParams params, final OnResultListener<OcrResponseResult> listener) {
//        Object obj=reflectionParam(ocrInstance,"context");
//        Context context=null;
//        if (obj!=null&&obj instanceof Context){
//            context=(Context)obj;
//        }else{
//            if (listener != null) {
//                listener.onError(null);
//            }
//            return;
//        }
//        File imageFile = params.getImageFile();
//        final File tempImage = new File(context.getCacheDir(), String.valueOf(System.currentTimeMillis()));
//        ImageUtil.resize(imageFile.getAbsolutePath(), tempImage.getAbsolutePath(), 1280, 1280);
//        params.setImageFile(tempImage);
//
//        OnResultListener l=new OnResultListener() {
//            public void onResult(Object result) {
//                Object res=urlAppendCommonParams(ocrInstance,url);
//                if (res!=null){
//                    Parser<OcrResponseResult> ocrResultParser = new OcrResultParser();
//                    HttpUtil.getInstance().post(String.valueOf(res), params, ocrResultParser, new OnResultListener<OcrResponseResult>() {
//                        public void onResult(OcrResponseResult result) {
//                            tempImage.delete();
//                            if (listener != null) {
//                                listener.onResult(result);
//                            }
//                        }
//
//                        public void onError(OCRError error) {
//                            tempImage.delete();
//                            if (listener != null) {
//                                listener.onError(error);
//                            }
//
//                        }
//                    });
//                }else{
//                    tempImage.delete();
//                    if (listener != null) {
//                        listener.onError(null);
//                    }
//                }
//            }
//
//            public void onError(OCRError error) {
//                tempImage.delete();
//                if (listener != null) {
//                    listener.onError(error);
//                }
//            }
//        };
//        getToken(ocrInstance,l);
//    }
//
//    private static void callOCR2(final OCR ocrInstance, final String url,final GeneralParams param, final OnResultListener<GeneralResult> listener) {
//        Object obj=reflectionParam(ocrInstance,"context");
//        Context context=null;
//        if (obj!=null&&obj instanceof Context){
//            context=(Context)obj;
//        }else{
//            if (listener != null) {
//                listener.onError(null);
//            }
//            return;
//        }
//        File imageFile = param.getImageFile();
//        final File tempImage = new File(OCRActivity.this.getCacheDir(), String.valueOf(System.currentTimeMillis()));
//        ImageUtil.resize(imageFile.getAbsolutePath(), tempImage.getAbsolutePath(), 1280, 1280);
//        param.setImageFile(tempImage);
//
//        OnResultListener l=new OnResultListener() {
//            public void onResult(Object result) {
//                Object res=urlAppendCommonParams(ocrInstance,url);
//                if (res!=null) {
//                    Parser<GeneralResult> generalResultParser = new GeneralResultParser();
//                    HttpUtil.getInstance().post(String.valueOf(res), param, generalResultParser, new OnResultListener<GeneralResult>() {
//                        public void onResult(GeneralResult result) {
//                            tempImage.delete();
//                            if (listener != null) {
//                                listener.onResult(result);
//                            }
//
//                        }
//
//                        public void onError(OCRError error) {
//                            tempImage.delete();
//                            if (listener != null) {
//                                listener.onError(error);
//                            }
//
//                        }
//                    });
//                }else{
//                    tempImage.delete();
//                    if (listener != null) {
//                        listener.onError(null);
//                    }
//                }
//            }
//
//            public void onError(OCRError error) {
//                tempImage.delete();
//                if (listener != null) {
//                    listener.onError(error);
//                }
//            }
//        };
//        getToken(ocrInstance,l);
//    }
//    private static Object urlAppendCommonParams(OCR ocrInstance, String url){
//        String targetUrl=url+(url.endsWith("?")?"":"?");
//        Object res=reflectionFunc(ocrInstance,"urlAppendCommonParams",new Object[]{targetUrl},new Class[]{String.class});
//        return res;
//    }
//    private static void getToken(OCR ocrInstance, final OnResultListener listener) {
//        reflectionFunc(ocrInstance,"getToken",new Object[]{listener},new Class[]{OnResultListener.class});
//    }
}
